/*
 * SurfaceViewをextendsさせたクラス
 * メインループなどはここにあります
 * 基本的にSurfaceViewを使用した時には決まった変数の使用
 * などがあるので、そういう変数やメソッドの末尾に
 * ”お決まり”と書いておきます
 */
package and.roid.shooting2;

import java.util.ArrayList;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainLoop extends SurfaceView implements SurfaceHolder.Callback, Runnable {
	private SurfaceHolder holder;// お決まり
	private Thread thread;// お決まり

	// どのActivityを使用しているかのための変数
	private Shooting2Activity s2a;
	private Mesod ms;
	private float disp_w, disp_h;
	private Drawable jikiimg, tamaimg;
	private Bitmap jikibit, tamabit;
	// 弾用、連続で重ならないようにの変数
	private boolean tamaflg;
	private int tamatime;

	/*
	 * 今回画面に表示させるオブジェクトは自機と弾です 全然違うオブジェクトですがObjectクラスをextends
	 * することで同じような変数として扱うことができます。 自機は一つのオブジェクトだけですが、弾はたくさん
	 * 表示します。しかし数は決まっていません。なので ArrayListを使用することにしました。
	 * 普通の配列変数では、いくつ配列を使用するかを決めないと いけませんが、ArrayListの場合は使用したいときに配列的な
	 * ものをいくつでも作成することができます。
	 */
	private ArrayList<Object> object = new ArrayList();

	// コンストラクタが二つあるけど気にしないように
	// こちらのコンストラクタは、自前でViewを実装するときに
	// 呼ばれるコンストラクタっぽい
	public MainLoop(Context context) {
		super(context);
		init(context);
	}

	// こちらはxml方式でViewを呼び出すときに呼ばれるぽい
	public MainLoop(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public void init(Context context) {
		holder = getHolder();// お決まり
		holder.addCallback(this);// お決まり
		holder.setFixedSize(getWidth(), getHeight());// お決まり
		/*
		 * s2a = (Shooting2Activity)context; よくわからないけども、私的には使用している（今現在
		 * 画面に表示させている）アプリの何か色々なものをcontext として受け取り、それがいまどのActivityのやつかとか
		 * そんな感じの雰囲気と思います。（キニシテナイ）
		 */
		s2a = (Shooting2Activity) context;
		ms = new Mesod();
		disp_w = s2a.disp_w;
		disp_h = s2a.disp_h;

		Resources resources = context.getResources();// 画像登録準備
		// ビットマップ方式で画像取り込み
		// ビットマップで取り込む理由として、使用したい大きさなどに変換できるので
		Bitmap img = BitmapFactory
				.decodeResource(resources, com.example.helloworld.R.drawable.jiki);
		// ここで画像分割
		// わざわざ画像の大きさをgetWidthgetHeightを使用するのは
		// 確実に大きさを図って分割するため
		jikibit = Bitmap.createBitmap(img, 0, 0, img.getWidth() / 2, img.getHeight());
		tamabit = Bitmap.createBitmap(img, img.getWidth() / 2, 0, img.getWidth() / 2,
				img.getHeight());

		/*
		 * Onjectクラスではインスタンス（実装）できないので ObjectクラスをextendsさせたJikiクラスを実装
		 * ArrayListを使用しているため、addでインスタンスしています メソッドなどを使用する場合はget(インデックス).でメソッドなど
		 * 色々呼び出したりします。 今回はArrayListの０番目の要素に自機が入っています
		 */
		object.add(new Jiki(disp_w, disp_h));
		object.get(0).Oint(jikibit, 240, 800, 0, 0, jikibit.getWidth(), jikibit.getHeight());

		tamaflg = true;
		tamatime = 5;

	}

	// implements Runnableを実装するとこのメソッドが自動追加
	// ここがメインループとなります
	public void run() {// お決まり
		Canvas c;
		Paint p = new Paint();
		p.setAntiAlias(true);

		while (thread != null) {
			c = holder.lockCanvas();// お決まり

			c.drawColor(Color.BLACK);

			/*
			 * 自機も弾も同じObjectの要素を持っているので インスタンス（実装）時に作成したいクラスを
			 * 指定しておけば、同じObjectクラスとして使用 することができます。わざわざ各オブジェクトの
			 * メソッドを呼ぶのではなく、共通しているObjectの メソッドを呼ぶことで解決しています
			 */
			for (int i = 0; i < object.size(); i++) {
				object.get(i).ODraw(c);
				object.get(i).OMove();
				/*
				 * 弾が画面外に出たらオブジェクト要素を消去します
				 */
				if (object.get(i).Ogetdead() == true)
					object.remove(i);
			}
			/*
			 * 弾を１發打ったら連続で打てないようになり、タイマー が０になったら打てるようにしています。
			 */
			if (tamaflg == false) {
				--tamatime;
				if (tamatime < 0) {
					tamatime = 5;
					tamaflg = true;
				}
			}

			holder.unlockCanvasAndPost(c);// お決まり

			try {
				Thread.sleep(50);// お決まり
			} catch (Exception e) {
			}
		}
	}

	public boolean onTouchEvent(MotionEvent event) {
		int action = event.getAction();
		int x = (int) event.getX();
		int y = (int) event.getY();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			/*
			 * 弾を打っていいよ状態であり自機画像範囲にタップしていれば Jitama(弾クラス)を作成する
			 */
			if (tamaflg == true && ms.RectTap(x, y, object.get(0).OgetTapRect()) == true) {
				object.add(new JiTama(disp_w, disp_h));
				object.get(object.size() - 1).Oint(tamabit, object.get(0).cx,
						object.get(0).cy - jikibit.getHeight(), 10, 30, tamabit.getWidth(),
						tamabit.getHeight());
				tamaflg = false;
			}
			break;
		case MotionEvent.ACTION_UP:
			break;
		case MotionEvent.ACTION_MOVE:
			/*
			 * タップ範囲にオブジェクトがあると自機の移動処理をします これがないと、ワープのような動きになる場合があります。
			 * 
			 * 今回は移動はしないようにして、タップすると弾を発射するように してみます
			 */
			// if(ms.RectTap(x, y, object.get(0).OgetTapRect()) == true)
			// object.get(0).OMove(x, y);

			break;
		}
		return true;
	}

	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
	}// お決まり

	public void surfaceCreated(SurfaceHolder arg0) {
		thread = new Thread(this);
		thread.start();
	}// お決まり

	public void surfaceDestroyed(SurfaceHolder arg0) {
		thread = null;
	}// お決まり

}
